package org.jsola.hr.task;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.log.XxlJobLogger;
import lombok.extern.slf4j.Slf4j;
import org.jsola.common.DateKit8;
import org.jsola.common.StrKit;
import org.jsola.contract.entity.ContractDO;
import org.jsola.hr.common.DateUtils;
import org.jsola.hr.common.task.TaskKit;
import org.jsola.hr.constant.HrConstants;
import org.jsola.hr.dto.TaskAddDTO;
import org.jsola.hr.entity.*;
import org.jsola.hr.provider.IContractProviderService;
import org.jsola.hr.provider.INoticeProviderService;
import org.jsola.hr.service.*;
import org.jsola.hr.vo.HrNoticeDateSettingVO;
import org.jsola.hr.vo.TaskRunParamVO;
import org.jsola.notice.constant.NoticeConstants;
import org.jsola.notice.constant.ReceiveDateTypeEnum;
import org.jsola.notice.entity.NoticeRuleSettingDO;
import org.jsola.notice.vo.NoticeRuleSettingVO;
import org.jsola.user.core.TokenUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 定时任务发送通知
 *
 * @author wcl
 */
@Slf4j
@Component
public class SendNoticeTask {

    @Autowired
    private IEmpInfoService empInfoService;

    @Autowired
    private INoticeProviderService noticeProviderService;

    @Autowired
    private TaskKit taskKit;

    @Autowired
    private IContractProviderService contractProviderService;

    @Autowired
    private IEmpContractService empContractService;

    @Autowired
    private IEmpPaperContractService empPaperContractService;

    @Autowired
    private IEmpChangesService empChangesService;

    @Autowired
    private IEmpSocPlanService empSocPlanService;

    /**
     * 提前提醒单位: 分钟
     */
    private static final Integer UNIT_MINUTE = 1;
    /**
     * 提前提醒单位: 小时
     */
    private static final Integer UNIT_HOUR = 2;
    /**
     * 提前提醒单位: 天
     */
    private static final Integer UNIT_DAY = 3;
    /**
     * 提前提醒单位: 当天
     */
    private static final Integer UNIT_CURRENT = 4;

    /**
     * 执行定时任务的的beanName
     */
    private static final String RUN_BEAN_NAME = "SendNoticeTask";

    /**
     * 员工退休发送通知
     */
    @XxlJob("retireTask")
    public ReturnT<String> retireTask(String params) {
        XxlJobLogger.log("==========定时任务开始: 员工退休发送通知");
        try {
            // 查询所有已转正的员工
            List<EmpInfoDO> empInfoDOList = empInfoService.listBeFormalTask();
            String desc = "员工退休发送通知";
            String fixedDesc = ReceiveDateTypeEnum.FIXED.getDesc();
            if (StringUtils.isEmpty(params)) {
                addTask(empInfoDOList, NoticeConstants.RETIRE, desc, fixedDesc, DateUtil.offsetDay(new Date(), 1));
            } else {
                addTask(empInfoDOList, NoticeConstants.RETIRE, desc, fixedDesc, new Date());
            }

        } catch (Exception e) {
            XxlJobLogger.log("==========定时任务失败: 员工退休发送通知,失败原因 : {}", e.getMessage());
            return ReturnT.FAIL;
        }
        XxlJobLogger.log("==========定时任务结束: 员工退休发送通知");
        return ReturnT.SUCCESS;
    }


    /**
     * 员工转正发送通知
     */
    @XxlJob("turnOfficialTask")
    public ReturnT<String> turnOfficial(String params) {
//        XxlJobLogger.log("==========定时任务开始: 员工转正发送通知");
//        try {
//            // 查询所有待转正的员工
//            List<EmpInfoDO> empInfoDOList = empInfoService.listTurnOfficialTask();
//            String desc = "员工转正发送通知";
//            String fixedDesc = ReceiveDateTypeEnum.FIXED.getDesc();
//            addTask(empInfoDOList, NoticeConstants.TURN_OFFICIAL, desc, fixedDesc);
//        } catch (Exception e) {
//            XxlJobLogger.log("==========定时任务失败: 员工转正发送通知,失败原因 : {}", e.getMessage());
//            return ReturnT.FAIL;
//        }
//        XxlJobLogger.log("==========定时任务结束: 员工转正发送通知");
//        return ReturnT.SUCCESS;
        return null;
    }

    /**
     * 员工入职发送通知
     */
    @XxlJob("inductionTask")
    public ReturnT<String> inductionTask(String params) {
//        XxlJobLogger.log("==========定时任务开始: 员工入职发送通知");
//        try {
//            // 查询所有待转入职的员工
//            List<EmpInfoDO> empInfoDOList = empInfoService.listInductionTask();
//            String desc = "员工入职发送通知";
//            String fixedDesc = ReceiveDateTypeEnum.FIXED.getDesc();
//            addTask(empInfoDOList, NoticeConstants.INDUCTION, desc, fixedDesc);
//        } catch (Exception e) {
//            XxlJobLogger.log("==========定时任务失败: 员工入职发送通知,失败原因 : {}", e.getMessage());
//            return ReturnT.FAIL;
//        }
//        XxlJobLogger.log("==========定时任务结束: 员工入职发送通知");
//        return ReturnT.SUCCESS;
        return null;
    }

    /**
     * 员工离职发送通知
     */
    @XxlJob("resignTask")
    public ReturnT<String> resignTask(String params) {
//        XxlJobLogger.log("==========定时任务开始: 员工离职发送通知");
//        try {
//            // 查询所有待转正的员工
//            List<EmpInfoDO> empInfoDOList = empInfoService.listResignTask();
//            String desc = "员工离职发送通知";
//            String fixedDesc = ReceiveDateTypeEnum.FIXED.getDesc();
//            addTask(empInfoDOList, NoticeConstants.RESIGN, desc, fixedDesc);
//
//        } catch (Exception e) {
//            XxlJobLogger.log("==========定时任务失败: 员工离职发送通知,失败原因 : {}", e.getMessage());
//            return ReturnT.FAIL;
//        }
//        XxlJobLogger.log("==========定时任务结束: 员工离职发送通知");
//        return ReturnT.SUCCESS;
        return null;
    }

    /**
     * 员工调岗发送通知
     */
    @XxlJob("transferTask")
    public ReturnT<String> transferTask(String params) {
//        XxlJobLogger.log("==========定时任务开始: 员工调岗发送通知");
//        try {
//            // 查询所有待转正的员工
//            List<EmpInfoDO> empInfoDOList = empInfoService.listTransferTask();
//            String desc = "员工调岗发送通知";
//            String fixedDesc = ReceiveDateTypeEnum.FIXED.getDesc();
//            addTask(empInfoDOList, NoticeConstants.TRANSFER, desc, fixedDesc);
//
//        } catch (Exception e) {
//            XxlJobLogger.log("==========定时任务失败: 员工调岗发送通知,失败原因 : {}", e.getMessage());
//            return ReturnT.FAIL;
//        }
//        XxlJobLogger.log("==========定时任务结束: 员工调岗发送通知");
//        return ReturnT.SUCCESS;
        return null;
    }

    /**
     * 合同到期发送通知
     */
    @XxlJob("contractExpireTask")
    public ReturnT<String> contractExpireTask(String params) {
        XxlJobLogger.log("==========定时任务开始: 合同到期发送通知");
        try {
            // 合同
            List<ContractDO> contractDOList = contractProviderService.listAllNoExpireContract()
                    .stream().filter(s -> StrKit.isNotEmpty(s.getSubjectId()))
                    .filter(s -> s.getEndDate().before(DateUtil.offsetDay(DateUtil.beginOfDay(new Date()), 91))).collect(Collectors.toList());
            // 电子合同
            List<EmpContractDO> empContractDOList = empContractService.listAllNoExpireContract().stream()
                    .filter(s -> s.getEndTime().before(DateUtil.offsetDay(DateUtil.beginOfDay(new Date()), 91))).collect(Collectors.toList());
            // 纸质合同
            List<EmpPaperContractDO> empPaperContractDOList = empPaperContractService.listAllNoExpireContract().stream()
                    .filter(s -> s.getEndTime().before(DateUtil.offsetDay(DateUtil.beginOfDay(new Date()), 91))).collect(Collectors.toList());
            ;
            TokenUser tokenUser = new TokenUser();
            tokenUser.setUserId("system");
            tokenUser.setSiteId(HrConstants.DEFAULT);
            List<TaskAddDTO> taskAddDTOListAll = new ArrayList<>();
            List<TaskAddDTO> taskAddDTOList;
            List<TaskAddDTO> taskAddDTOList1;
            List<TaskAddDTO> taskAddDTOList2;
            if (StringUtils.isEmpty(params)) {
                taskAddDTOList = addContract(contractDOList, DateUtil.offsetDay(new Date(), 1));
                taskAddDTOList1 = addEmpContract(empContractDOList, DateUtil.offsetDay(new Date(), 1));
                taskAddDTOList2 = addEmpPaperContract(empPaperContractDOList, DateUtil.offsetDay(new Date(), 1));
            } else {
                taskAddDTOList = addContract(contractDOList, new Date());
                taskAddDTOList1 = addEmpContract(empContractDOList, new Date());
                taskAddDTOList2 = addEmpPaperContract(empPaperContractDOList, new Date());

            }
            taskAddDTOListAll.addAll(taskAddDTOList);
            taskAddDTOListAll.addAll(taskAddDTOList1);
            taskAddDTOListAll.addAll(taskAddDTOList2);
            taskKit.addTaskList(taskAddDTOListAll, tokenUser);

        } catch (Exception e) {
            XxlJobLogger.log("==========定时任务失败: 合同到期发送通知,失败原因 : {}", e.getMessage());
            return ReturnT.FAIL;
        }
        XxlJobLogger.log("==========定时任务结束: 合同到期发送通知");
        return ReturnT.SUCCESS;
    }

    /**
     * 添加合同
     */
    private List<TaskAddDTO> addContract(List<ContractDO> contractDOList, Date needRunDate) {
        Map<String, List<ContractDO>> companyIdListMap = contractDOList.parallelStream()
                .collect(Collectors.groupingBy(ContractDO::getSubjectId));
        List<NoticeRuleSettingDO> noticeRuleSettingDOList = noticeProviderService.listByNoticeTypeCode(NoticeConstants.CONTRACT_EXPIRES)
                .stream().filter(NoticeRuleSettingDO::getEnableStatus).collect(Collectors.toList());
        List<TaskAddDTO> allTaskAddDTOList = new ArrayList<>();
        //需要发送提醒的日期
        Date dateTime = needRunDate;
        for (NoticeRuleSettingDO noticeRuleSettingDO : noticeRuleSettingDOList) {
            String companyId = noticeRuleSettingDO.getCompanyId();
            // 待转正员工
            List<ContractDO> contractDOS = companyIdListMap.get(companyId);
            if (CollectionUtils.isEmpty(contractDOS)) {
                continue;
            }
            // 接收时间类型; 1:实时 2:提前提醒 3:固定时间
            Integer receiveDateType = noticeRuleSettingDO.getReceiveDateType();
            List<TaskAddDTO> taskAddDTOList = new ArrayList<>();
            TaskRunParamVO taskParam = new TaskRunParamVO();
            HrNoticeDateSettingVO hrNoticeDateSettingVO = parseDate(noticeRuleSettingDO);
            // 实时
            if (ReceiveDateTypeEnum.RIGHT_NOW.getValue().equals(receiveDateType)) {
                taskAddDTOList = contractDOS
                        .parallelStream()
                        .map(contractDO -> {
                            Date runDate = null;
                            TaskAddDTO taskAddDTO = new TaskAddDTO();
                            if (StringUtils.isEmpty(hrNoticeDateSettingVO.getAppointTime())) {
                                hrNoticeDateSettingVO.setAppointTime("9:00:00");
                            }
                            String[] split = hrNoticeDateSettingVO.getAppointTime().split(":");
                            //需要发送提醒的日期,明天的
                            if (DateUtil.isSameDay(contractDO.getEndDate(), dateTime)) {
                                runDate = DateUtil.offsetSecond(DateUtil.beginOfDay(dateTime), Integer.parseInt(split[0]) * 60 * 60 + Integer.parseInt(split[1]) * 60 + Integer.parseInt(split[2]));
                            } else {
                                return null;
                            }
                            TaskRunParamVO taskRunParamVO = new TaskRunParamVO();
                            taskRunParamVO.setSubjectId(contractDO.getId() + "");
                            taskAddDTO.setRunParam(JSON.toJSONString(taskRunParamVO));
                            if (runDate == null) {
                                return null;
                            }
                            taskAddDTO.setSubjectType(NoticeConstants.CONTRACT_EXPIRES);
                            taskAddDTO.setSubjectId(companyId);
                            taskAddDTO.setRunDate(runDate);
                            taskAddDTO.setDescription("合同到期提醒");
                            taskAddDTO.setRunBeanName("SendNoticeTask");
                            taskAddDTO.setStatus(false);
                            return taskAddDTO;
                        }).filter(Objects::nonNull).collect(Collectors.toList());
            }
            // 提前发送
            else if (ReceiveDateTypeEnum.BEFORE.getValue().equals(receiveDateType)) {
                taskAddDTOList = contractDOS.parallelStream().map(contractDO -> {
                    if (Objects.isNull(contractDO.getEndDate())) {
                        return null;
                    }
                    Date runDate = null;
                    TaskAddDTO taskAddDTO = new TaskAddDTO();
                    //通知天
                    DateTime offsetDay = DateUtil.offsetDay(contractDO.getEndDate(), -hrNoticeDateSettingVO.getNumber());
                    if (DateUtil.isSameDay(offsetDay, dateTime)) {
                        if (StringUtils.isEmpty(hrNoticeDateSettingVO.getAppointTime())) {
                            hrNoticeDateSettingVO.setAppointTime("9:00:00");
                        }
                        String[] split = hrNoticeDateSettingVO.getAppointTime().split(":");
                        runDate = DateUtil.offsetSecond(DateUtil.beginOfDay(dateTime), Integer.parseInt(split[0]) * 60 * 60 + Integer.parseInt(split[1]) * 60 + Integer.parseInt(split[2]));
                        TaskRunParamVO taskRunParamVO = new TaskRunParamVO();
                        taskRunParamVO.setSubjectId(contractDO.getId() + "");
                        taskAddDTO.setRunParam(JSON.toJSONString(taskRunParamVO));
                    } else {
                        return null;
                    }
                    if (runDate == null) {
                        return null;
                    }
                    taskAddDTO.setSubjectType(NoticeConstants.CONTRACT_EXPIRES);
                    taskAddDTO.setSubjectId(companyId);
                    taskAddDTO.setRunDate(runDate);
                    taskAddDTO.setDescription("合同到期提醒");
                    taskAddDTO.setRunBeanName("SentNoticeTask");
                    taskAddDTO.setStatus(false);
                    return taskAddDTO;
                }).filter(Objects::nonNull).collect(Collectors.toList());
            }
            // 固定时间发送
            else if (ReceiveDateTypeEnum.FIXED.getValue().equals(receiveDateType)) {
                Integer day = hrNoticeDateSettingVO.getDay();
                String time = hrNoticeDateSettingVO.getTime();
                Date runDate = getFixedDate(day, time);
                if (!DateUtil.isSameDay(dateTime, runDate)) {
                    continue;
                }
                //保留日期为设置日期到一月后之内的人员
                contractDOS.removeIf(contractDO -> contractDO.getEndDate().before(DateUtil.beginOfDay(runDate)) || DateUtil.offsetMonth(DateUtil.beginOfDay(runDate), 1).before(contractDO.getEndDate()));
                if (CollectionUtils.isEmpty(contractDOS)) {
                    continue;
                }
                taskAddDTOList = contractDOS.parallelStream().map(
                        contractDO -> {
                            TaskAddDTO taskAddDTO = new TaskAddDTO();
                            taskAddDTO.setSubjectType(NoticeConstants.CONTRACT_EXPIRES);
                            taskAddDTO.setSubjectId(companyId);
                            taskAddDTO.setRunDate(runDate);
                            taskParam.setSubjectId(contractDO.getId() + "");
                            taskAddDTO.setRunParam(JSON.toJSONString(taskParam));
                            taskAddDTO.setDescription("合同到期提醒");
                            taskAddDTO.setRunBeanName("SentNoticeTask");
                            taskAddDTO.setStatus(false);
                            return taskAddDTO;
                        }).filter(Objects::nonNull).collect(Collectors.toList()
                );
            }
            allTaskAddDTOList.addAll(taskAddDTOList);
        }
        return allTaskAddDTOList;
    }

    /**
     * 添加花名册电子合同
     */
    public List<TaskAddDTO> addEmpContract(List<EmpContractDO> empContractDOList, Date needRunDate) {
        Map<String, List<EmpContractDO>> companyIdListMap = empContractDOList.parallelStream()
                .collect(Collectors.groupingBy(EmpContractDO::getCompanyId));
        List<NoticeRuleSettingDO> noticeRuleSettingDOList = noticeProviderService.listByNoticeTypeCode(NoticeConstants.CONTRACT_EXPIRES);
        List<TaskAddDTO> allTaskAddDTOList = new ArrayList<>();
        //需要发送提醒的日期
        Date dateTime = needRunDate;
        for (NoticeRuleSettingDO noticeRuleSettingDO : noticeRuleSettingDOList) {
            String companyId = noticeRuleSettingDO.getCompanyId();
            List<EmpContractDO> empContractDOS = companyIdListMap.get(companyId);
            if (CollectionUtils.isEmpty(empContractDOS)) {
                continue;
            }
            // 接收时间类型; 1:实时 2:提前提醒 3:固定时间
            Integer receiveDateType = noticeRuleSettingDO.getReceiveDateType();
            List<TaskAddDTO> taskAddDTOList = new ArrayList<>();
            TaskRunParamVO taskParam = new TaskRunParamVO();
            HrNoticeDateSettingVO hrNoticeDateSettingVO = parseDate(noticeRuleSettingDO);
            // 实时
            if (ReceiveDateTypeEnum.RIGHT_NOW.getValue().equals(receiveDateType)) {
                taskAddDTOList = empContractDOS
                        .parallelStream()
                        .map(empContractDO -> {
                            Date runDate = null;
                            TaskAddDTO taskAddDTO = new TaskAddDTO();
                            if (StringUtils.isEmpty(hrNoticeDateSettingVO.getAppointTime())) {
                                hrNoticeDateSettingVO.setAppointTime("9:00:00");
                            }
                            String[] split = hrNoticeDateSettingVO.getAppointTime().split(":");
                            //需要发送提醒的日期,明天的
                            if (DateUtil.isSameDay(empContractDO.getEndTime(), dateTime)) {
                                runDate = DateUtil.offsetSecond(DateUtil.beginOfDay(dateTime), Integer.parseInt(split[0]) * 60 * 60 + Integer.parseInt(split[1]) * 60 + Integer.parseInt(split[2]));
                            } else {
                                return null;
                            }
                            TaskRunParamVO taskRunParamVO = new TaskRunParamVO();
                            taskRunParamVO.setSubjectId(empContractDO.getId());
                            taskAddDTO.setRunParam(JSON.toJSONString(taskRunParamVO));
                            if (runDate == null) {
                                return null;
                            }
                            taskAddDTO.setSubjectType(NoticeConstants.CONTRACT_EXPIRES);
                            taskAddDTO.setSubjectId(companyId);
                            taskAddDTO.setRunDate(runDate);
                            taskAddDTO.setDescription("合同到期提醒");
                            taskAddDTO.setRunBeanName("SendNoticeTask");
                            taskAddDTO.setStatus(false);
                            return taskAddDTO;
                        }).filter(Objects::nonNull).collect(Collectors.toList());
            }
            // 提前发送
            else if (ReceiveDateTypeEnum.BEFORE.getValue().equals(receiveDateType)) {
                taskAddDTOList = empContractDOS.parallelStream().map(empContractDO -> {
                    if (Objects.isNull(empContractDO.getEndTime())) {
                        return null;
                    }
                    Date runDate = null;
                    TaskAddDTO taskAddDTO = new TaskAddDTO();
                    //通知天
                    DateTime offsetDay = DateUtil.offsetDay(empContractDO.getEndTime(), -hrNoticeDateSettingVO.getNumber());
                    if (DateUtil.isSameDay(offsetDay, dateTime)) {
                        if (StringUtils.isEmpty(hrNoticeDateSettingVO.getAppointTime())) {
                            hrNoticeDateSettingVO.setAppointTime("9:00:00");
                        }
                        String[] split = hrNoticeDateSettingVO.getAppointTime().split(":");
                        runDate = DateUtil.offsetSecond(DateUtil.beginOfDay(dateTime), Integer.parseInt(split[0]) * 60 * 60 + Integer.parseInt(split[1]) * 60 + Integer.parseInt(split[2]));
                        TaskRunParamVO taskRunParamVO = new TaskRunParamVO();
                        taskRunParamVO.setSubjectId(empContractDO.getId());
                        taskAddDTO.setRunParam(JSON.toJSONString(taskRunParamVO));
                    } else {
                        return null;
                    }
                    if (runDate == null) {
                        return null;
                    }
                    taskAddDTO.setSubjectType(NoticeConstants.CONTRACT_EXPIRES);
                    taskAddDTO.setSubjectId(companyId);
                    taskAddDTO.setRunDate(runDate);
                    taskAddDTO.setDescription("合同到期提醒");
                    taskAddDTO.setRunBeanName("SentNoticeTask");
                    taskAddDTO.setStatus(false);
                    return taskAddDTO;
                }).filter(Objects::nonNull).collect(Collectors.toList());
            }
            // 固定时间发送
            else if (ReceiveDateTypeEnum.FIXED.getValue().equals(receiveDateType)) {
                Integer day = hrNoticeDateSettingVO.getDay();
                String time = hrNoticeDateSettingVO.getTime();
                Date runDate = getFixedDate(day, time);
                if (!DateUtil.isSameDay(dateTime, runDate)) {
                    continue;
                }
                //保留日期为设置日期到一月后之内的人员
                empContractDOS.removeIf(empContractDO -> empContractDO.getEndTime().before(DateUtil.beginOfDay(runDate)) || DateUtil.offsetMonth(DateUtil.beginOfDay(runDate), 1).before(empContractDO.getEndTime()));
                if (CollectionUtils.isEmpty(empContractDOS)) {
                    continue;
                }
                taskAddDTOList = empContractDOS.parallelStream().map(
                        empContractDO -> {
                            TaskAddDTO taskAddDTO = new TaskAddDTO();
                            taskAddDTO.setSubjectType(NoticeConstants.CONTRACT_EXPIRES);
                            taskAddDTO.setSubjectId(companyId);
                            taskAddDTO.setRunDate(runDate);
                            taskParam.setSubjectId(empContractDO.getId());
                            taskAddDTO.setRunParam(JSON.toJSONString(taskParam));
                            taskAddDTO.setDescription("合同到期提醒");
                            taskAddDTO.setRunBeanName("SentNoticeTask");
                            taskAddDTO.setStatus(false);
                            return taskAddDTO;
                        }).filter(Objects::nonNull).collect(Collectors.toList()
                );
            }
            allTaskAddDTOList.addAll(taskAddDTOList);
        }
        return allTaskAddDTOList;
    }

    /**
     * 添加花名册纸质合同
     */
    public List<TaskAddDTO> addEmpPaperContract(List<EmpPaperContractDO> empPaperContractDOList, Date needRunDate) {
        Map<String, List<EmpPaperContractDO>> companyIdListMap = empPaperContractDOList.parallelStream()
                .collect(Collectors.groupingBy(EmpPaperContractDO::getCompanyId));
        List<NoticeRuleSettingDO> noticeRuleSettingDOList = noticeProviderService.listByNoticeTypeCode(NoticeConstants.CONTRACT_EXPIRES);
        List<TaskAddDTO> allTaskAddDTOList = new ArrayList<>();
        //需要发送提醒的日期
        Date dateTime = needRunDate;
        for (NoticeRuleSettingDO noticeRuleSettingDO : noticeRuleSettingDOList) {
            String companyId = noticeRuleSettingDO.getCompanyId();
            List<EmpPaperContractDO> empPaperContractDOS = companyIdListMap.get(companyId);
            if (CollectionUtils.isEmpty(empPaperContractDOS)) {
                continue;
            }
            // 接收时间类型; 1:实时 2:提前提醒 3:固定时间
            Integer receiveDateType = noticeRuleSettingDO.getReceiveDateType();
            List<TaskAddDTO> taskAddDTOList = new ArrayList<>();
            TaskRunParamVO taskParam = new TaskRunParamVO();
            HrNoticeDateSettingVO hrNoticeDateSettingVO = parseDate(noticeRuleSettingDO);
            // 实时
            if (ReceiveDateTypeEnum.RIGHT_NOW.getValue().equals(receiveDateType)) {
                taskAddDTOList = empPaperContractDOS
                        .parallelStream()
                        .map(empPaperContractDO -> {
                            Date runDate = null;
                            TaskAddDTO taskAddDTO = new TaskAddDTO();
                            if (StringUtils.isEmpty(hrNoticeDateSettingVO.getAppointTime())) {
                                hrNoticeDateSettingVO.setAppointTime("9:00:00");
                            }
                            String[] split = hrNoticeDateSettingVO.getAppointTime().split(":");
                            //需要发送提醒的日期,明天的
                            if (DateUtil.isSameDay(empPaperContractDO.getEndTime(), dateTime)) {
                                runDate = DateUtil.offsetSecond(DateUtil.beginOfDay(dateTime), Integer.parseInt(split[0]) * 60 * 60 + Integer.parseInt(split[1]) * 60 + Integer.parseInt(split[2]));
                            } else {
                                return null;
                            }
                            TaskRunParamVO taskRunParamVO = new TaskRunParamVO();
                            taskRunParamVO.setSubjectId(empPaperContractDO.getId());
                            taskAddDTO.setRunParam(JSON.toJSONString(taskRunParamVO));
                            if (runDate == null) {
                                return null;
                            }
                            taskAddDTO.setSubjectType(NoticeConstants.CONTRACT_EXPIRES);
                            taskAddDTO.setSubjectId(companyId);
                            taskAddDTO.setRunDate(runDate);
                            taskAddDTO.setDescription("合同到期提醒");
                            taskAddDTO.setRunBeanName("SendNoticeTask");
                            taskAddDTO.setStatus(false);
                            return taskAddDTO;
                        }).filter(Objects::nonNull).collect(Collectors.toList());
            }
            // 提前发送
            else if (ReceiveDateTypeEnum.BEFORE.getValue().equals(receiveDateType)) {
                taskAddDTOList = empPaperContractDOS.parallelStream().map(empPaperContractDO -> {
                    if (Objects.isNull(empPaperContractDO.getEndTime())) {
                        return null;
                    }
                    Date runDate = null;
                    TaskAddDTO taskAddDTO = new TaskAddDTO();
                    //通知天
                    DateTime offsetDay = DateUtil.offsetDay(empPaperContractDO.getEndTime(), -hrNoticeDateSettingVO.getNumber());
                    if (DateUtil.isSameDay(offsetDay, dateTime)) {
                        if (StringUtils.isEmpty(hrNoticeDateSettingVO.getAppointTime())) {
                            hrNoticeDateSettingVO.setAppointTime("9:00:00");
                        }
                        String[] split = hrNoticeDateSettingVO.getAppointTime().split(":");
                        runDate = DateUtil.offsetSecond(DateUtil.beginOfDay(dateTime), Integer.parseInt(split[0]) * 60 * 60 + Integer.parseInt(split[1]) * 60 + Integer.parseInt(split[2]));
                        TaskRunParamVO taskRunParamVO = new TaskRunParamVO();
                        taskRunParamVO.setSubjectId(empPaperContractDO.getId());
                        taskAddDTO.setRunParam(JSON.toJSONString(taskRunParamVO));
                    } else {
                        return null;
                    }
                    if (runDate == null) {
                        return null;
                    }
                    taskAddDTO.setSubjectType(NoticeConstants.CONTRACT_EXPIRES);
                    taskAddDTO.setSubjectId(companyId);
                    taskAddDTO.setRunDate(runDate);
                    taskAddDTO.setDescription("合同到期提醒");
                    taskAddDTO.setRunBeanName("SentNoticeTask");
                    taskAddDTO.setStatus(false);
                    return taskAddDTO;
                }).filter(Objects::nonNull).collect(Collectors.toList());
            }
            // 固定时间发送
            else if (ReceiveDateTypeEnum.FIXED.getValue().equals(receiveDateType)) {
                Integer day = hrNoticeDateSettingVO.getDay();
                String time = hrNoticeDateSettingVO.getTime();
                Date runDate = getFixedDate(day, time);
                if (!DateUtil.isSameDay(dateTime, runDate)) {
                    continue;
                }
                //保留日期为设置日期到一月后之内的人员
                empPaperContractDOS.removeIf(empPaperContractDO -> empPaperContractDO.getEndTime().before(DateUtil.beginOfDay(runDate)) || DateUtil.offsetMonth(DateUtil.beginOfDay(runDate), 1).before(empPaperContractDO.getEndTime()));
                if (CollectionUtils.isEmpty(empPaperContractDOS)) {
                    continue;
                }
                taskAddDTOList = empPaperContractDOS.parallelStream().map(
                        empPaperContractDO -> {
                            TaskAddDTO taskAddDTO = new TaskAddDTO();
                            taskAddDTO.setSubjectType(NoticeConstants.CONTRACT_EXPIRES);
                            taskAddDTO.setSubjectId(companyId);
                            taskAddDTO.setRunDate(runDate);
                            taskParam.setSubjectId(empPaperContractDO.getId());
                            taskAddDTO.setRunParam(JSON.toJSONString(taskParam));
                            taskAddDTO.setDescription("合同到期提醒");
                            taskAddDTO.setRunBeanName("SentNoticeTask");
                            taskAddDTO.setStatus(false);
                            return taskAddDTO;
                        }).filter(Objects::nonNull).collect(Collectors.toList()
                );
            }
            allTaskAddDTOList.addAll(taskAddDTOList);
        }
        return allTaskAddDTOList;
    }

    /**
     * 添加到定时任务表
     */
    public void addTask(List<EmpInfoDO> empInfoDOList, String subjectType, String desc, String fixedDesc, Date needRunDate) {
        // companyId - 员工集合 Map
        Map<String, List<EmpInfoDO>> companyIdEmpInfoListMap = empInfoDOList.parallelStream()
                .collect(Collectors.groupingBy(EmpInfoDO::getCompanyId));
        List<NoticeRuleSettingDO> noticeRuleSettingDOList = noticeProviderService.listByNoticeTypeCode(subjectType)
                .stream().filter(p -> p.getEnableStatus()).collect(Collectors.toList());
        TokenUser tokenUser = new TokenUser();
        tokenUser.setUserId("system");
        tokenUser.setSiteId(HrConstants.DEFAULT);
        List<TaskAddDTO> allTaskAddDTOList = new ArrayList<>();
        //需要发送退休提醒的日期
        Date dateTime = needRunDate;
        for (NoticeRuleSettingDO noticeRuleSettingDO : noticeRuleSettingDOList) {
            String companyId = noticeRuleSettingDO.getCompanyId();
            // 公司员工
            List<EmpInfoDO> empInfoDOList1 = companyIdEmpInfoListMap.get(companyId);
            if (CollectionUtils.isEmpty(empInfoDOList1)) {
                continue;
            }
            // 接收时间类型; 1:实时 2:提前提醒 3:固定时间
            Integer receiveDateType = noticeRuleSettingDO.getReceiveDateType();
            List<TaskAddDTO> taskAddDTOList = new ArrayList<>();
            //实时
            if (ReceiveDateTypeEnum.RIGHT_NOW.getValue().equals(receiveDateType)) {
                HrNoticeDateSettingVO hrNoticeDateSettingVO = parseDate(noticeRuleSettingDO);
                taskAddDTOList = empInfoDOList1
                        .parallelStream()
                        .map(emp -> {
                            Date runDate = null;
                            TaskAddDTO taskAddDTO = new TaskAddDTO();
                            //退休
                            if (NoticeConstants.RETIRE.equals(subjectType)) {
                                if (StringUtils.isEmpty(hrNoticeDateSettingVO.getAppointTime())) {
                                    hrNoticeDateSettingVO.setAppointTime("9:00:00");
                                }
                                String[] split = hrNoticeDateSettingVO.getAppointTime().split(":");
                                if (DateUtil.isSameDay(emp.getRetirementDate(), dateTime)) {
                                    runDate = DateUtil.offsetSecond(DateUtil.beginOfDay(dateTime), Integer.parseInt(split[0]) * 60 * 60 + Integer.parseInt(split[1]) * 60 + Integer.parseInt(split[2]));
                                } else {
                                    return null;
                                }
                                TaskRunParamVO taskRunParamVO = new TaskRunParamVO();
                                taskRunParamVO.setSubjectId(emp.getId());
                                taskRunParamVO.setIsFixedNotice(true);
                                taskAddDTO.setRunParam(JSON.toJSONString(taskRunParamVO));
                            }
                            if (runDate == null) {
                                return null;
                            }
                            taskAddDTO.setSubjectType(subjectType);
                            taskAddDTO.setSubjectId(companyId);
                            taskAddDTO.setRunDate(runDate);
                            taskAddDTO.setDescription(desc);
                            taskAddDTO.setRunBeanName("SendNoticeTask");
                            taskAddDTO.setStatus(false);
                            return taskAddDTO;
                        }).filter(Objects::nonNull).collect(Collectors.toList());
            }
            // 提前发送
            else if (ReceiveDateTypeEnum.BEFORE.getValue().equals(receiveDateType)) {
                HrNoticeDateSettingVO hrNoticeDateSettingVO = parseDate(noticeRuleSettingDO);
                taskAddDTOList = empInfoDOList1
                        .parallelStream()
                        .map(emp -> {
                            Date runDate = null;
                            TaskAddDTO taskAddDTO = new TaskAddDTO();
                            //退休
                            if (NoticeConstants.RETIRE.equals(subjectType)) {

                                //通知天
                                DateTime offsetDay = DateUtil.offsetDay(emp.getRetirementDate(), -hrNoticeDateSettingVO.getNumber());
                                if (DateUtil.isSameDay(offsetDay, dateTime)) {
                                    if (StringUtils.isEmpty(hrNoticeDateSettingVO.getAppointTime())) {
                                        hrNoticeDateSettingVO.setAppointTime("9:00:00");
                                    }
                                    String[] split = hrNoticeDateSettingVO.getAppointTime().split(":");
                                    runDate = DateUtil.offsetSecond(DateUtil.beginOfDay(dateTime), Integer.parseInt(split[0]) * 60 * 60 + Integer.parseInt(split[1]) * 60 + Integer.parseInt(split[2]));
                                    TaskRunParamVO taskRunParamVO = new TaskRunParamVO();
                                    taskRunParamVO.setSubjectId(emp.getId());
                                    taskRunParamVO.setIsFixedNotice(true);
                                    taskAddDTO.setRunParam(JSON.toJSONString(taskRunParamVO));
                                } else {
                                    return null;
                                }
                            }
                            if (runDate == null) {
                                return null;
                            }
                            taskAddDTO.setSubjectType(subjectType);
                            taskAddDTO.setSubjectId(companyId);
                            taskAddDTO.setRunDate(runDate);
                            taskAddDTO.setDescription(desc);
                            taskAddDTO.setRunBeanName("SentNoticeTask");
                            taskAddDTO.setStatus(false);
                            return taskAddDTO;
                        }).filter(Objects::nonNull).collect(Collectors.toList());
            }
            // 固定时间发送
            else if (ReceiveDateTypeEnum.FIXED.getValue().equals(receiveDateType)) {
                //退休暂时没固定通知
//                HrNoticeDateSettingVO hrNoticeDateSettingVO = JSON.parseObject(noticeRuleSettingDO.getReceiveDateJson(), HrNoticeDateSettingVO.class);
//                Integer day = hrNoticeDateSettingVO.getDay();
//                String time = hrNoticeDateSettingVO.getTime();
//                Date runDate = getFixedDate(day, time);
//                //保留日期为设置日期到一月后之内的人员
//
//                empInfoDOList1.removeIf(empInfoDO -> empInfoDO.getRetirementDate().before(runDate) || DateUtil.offsetMonth(runDate, 1).before(empInfoDO.getRetirementDate()));
//                if (CollectionUtils.isEmpty(empInfoDOList1)){
//                    continue;
//                }
//                String empIdList = empInfoDOList1.parallelStream()
//                        .map(EmpInfoDO::getId).collect(Collectors.joining(","));
//                if(subjectType.equals(NoticeConstants.RETIRE)){
//                    for (EmpInfoDO empInfoDO : empInfoDOList1) {
//                        TaskAddDTO taskAddDTO = new TaskAddDTO();
//                        taskAddDTO.setSubjectType(subjectType);
//                        taskAddDTO.setSubjectId(companyId);
//                        taskAddDTO.setRunDate(runDate);
//                        taskAddDTO.setRunType(companyId);
//                        taskAddDTO.setDescription(desc);
//                        taskAddDTO.setRunBeanName("SentNoticeTask");
//                        taskAddDTO.setStatus(false);
//                        TaskRunParamVO taskRunParamVO = new TaskRunParamVO();
//                        taskRunParamVO.setSubjectId(empInfoDO.getId());
//                        taskRunParamVO.setIsFixedNotice(true);
//                        taskAddDTO.setRunParam(JSON.toJSONString(taskRunParamVO));
//                        taskAddDTOList.add(taskAddDTO);
//                    }
//                }else {
//                    TaskAddDTO taskAddDTO = new TaskAddDTO();
//                    taskAddDTO.setSubjectType(subjectType);
//                    taskAddDTO.setSubjectId(empIdList);
//                    taskAddDTO.setRunDate(runDate);
//                    taskAddDTO.setRunType(companyId);
//                    taskAddDTO.setDescription(fixedDesc);
//                    taskAddDTO.setRunBeanName("SentNoticeTask");
//                    taskAddDTO.setStatus(false);
//                    taskAddDTOList.add(taskAddDTO);
//                }
            }
            allTaskAddDTOList.addAll(taskAddDTOList);
        }
        taskKit.addTaskList(allTaskAddDTOList, tokenUser);
    }

    /**
     * 添加到定时任务表
     *
     * @param subjectId   业务id
     * @param subjectType 通知类型code
     * @param companyId   用工单位id
     * @param preRunDate  预计通知时间（可能根据设置重新计算）
     * @param description 描述
     * @param tokenUser   当前用户
     */
    public void addTask(String subjectId, String subjectType, String companyId, Date preRunDate,
                        String description, TokenUser tokenUser) {
        NoticeRuleSettingVO noticeRuleSettingDO = noticeProviderService.selectByTypeCodeAndCompany(HrConstants.HR_SUBJECT_TYPE,
                subjectType, companyId);
        if (noticeRuleSettingDO == null) {
            log.error("消息发送失败，noticeRuleSettingDO不存在，subjectType：{}，companyId：{}", subjectType, companyId);
            return;
        }
        // 接收时间类型; 1:实时 2:提前提醒 3:固定时间
        Integer receiveDateType = noticeRuleSettingDO.getReceiveDateType();
        TaskRunParamVO taskParam = new TaskRunParamVO();
        TaskAddDTO taskAddDTO = new TaskAddDTO();
        // 实时发送
        if (ReceiveDateTypeEnum.RIGHT_NOW.getValue().equals(receiveDateType)) {
            taskAddDTO.setSubjectType(subjectType);
            taskAddDTO.setSubjectId(companyId);
            taskParam.setSubjectId(subjectId);
            taskAddDTO.setRunParam(JSON.toJSONString(taskParam));
            taskAddDTO.setRunDate(preRunDate);
            taskAddDTO.setRunBeanName(RUN_BEAN_NAME);
            taskAddDTO.setDescription(description);
            taskAddDTO.setStatus(false);
        }
        // 提前发送
        else if (ReceiveDateTypeEnum.BEFORE.getValue().equals(receiveDateType)) {
            HrNoticeDateSettingVO hrNoticeDateSettingVO = parseDate(noticeRuleSettingDO.to(NoticeRuleSettingDO.class));
            // 提前时间
            long before = hrNoticeDateSettingVO.getSecond() * 1000L;
            long time = preRunDate.getTime();
            long runTime = time - before;
            Date runDate = DateUtil.offsetHour(DateUtil.beginOfDay(new Date(runTime)), 9);
            taskAddDTO.setSubjectType(subjectType);
            taskAddDTO.setSubjectId(companyId);
            taskParam.setSubjectId(subjectId);
            taskAddDTO.setRunParam(JSON.toJSONString(taskParam));
            taskAddDTO.setRunDate(runDate);
            taskAddDTO.setRunBeanName(RUN_BEAN_NAME);
            taskAddDTO.setDescription(description);
            taskAddDTO.setStatus(false);
        }
        // 固定时间发送
        else if (ReceiveDateTypeEnum.FIXED.getValue().equals(receiveDateType)) {
            HrNoticeDateSettingVO hrNoticeDateSettingVO = JSON.parseObject(noticeRuleSettingDO.getReceiveDateJson(), HrNoticeDateSettingVO.class);
            Integer day = hrNoticeDateSettingVO.getDay();
            String time = hrNoticeDateSettingVO.getTime();
            Date runDate = getFixedDate(day, time);
            // 如果当前天比设置的固定时间大, 不发通知
            taskAddDTO.setSubjectType(subjectType);
            taskAddDTO.setSubjectId(companyId);
            taskAddDTO.setRunDate(runDate);
            taskParam.setSubjectId(subjectId);
            taskParam.setIsFixedNotice(true);
            taskAddDTO.setRunParam(JSON.toJSONString(taskParam));
            taskAddDTO.setRunBeanName(RUN_BEAN_NAME);
            taskAddDTO.setDescription(description);
            taskAddDTO.setStatus(false);
        }
        taskKit.addTask(taskAddDTO, tokenUser);
    }

    /**
     * 员工增减员确认发送通知定时任务
     */
    @XxlJob("increaseDecreaseTask")
    public ReturnT<String> increaseDecrease(String params) {
        XxlJobLogger.log("==========定时任务开始: 检测员工增减员确认发送通知");
        try {
            // 查询所有未反馈的员工
            List<EmpSocPlanDO> empSocPlanList = empSocPlanService.selectAllNotFeedback();
            // companyId - 员工集合 Map
            Map<String, List<EmpSocPlanDO>> empSocPlanListGroupCompany = empSocPlanList.parallelStream()
                    .collect(Collectors.groupingBy(EmpSocPlanDO::getCompanyId));
            // 查询增减员的通知规则,一个公司只有一种增减员规则
            List<NoticeRuleSettingDO> noticeRuleSettingDOList = noticeProviderService.listByNoticeTypeCode(NoticeConstants.INCREMENT);
            TokenUser tokenUser = new TokenUser();
            tokenUser.setUserId("system");
            tokenUser.setSiteId(HrConstants.DEFAULT);
            for (NoticeRuleSettingDO noticeRuleSettingDO : noticeRuleSettingDOList) {
                // 接收时间类型; 1:实时 2:提前提醒 3:固定时间
                Integer receiveDateType = noticeRuleSettingDO.getReceiveDateType();
                // 固定时间发送
                if (ReceiveDateTypeEnum.FIXED.getValue().equals(receiveDateType)) {
                    String companyId = noticeRuleSettingDO.getCompanyId();
                    // 解析到规则中的需要提醒的日期
                    HrNoticeDateSettingVO hrNoticeDateSettingVO =
                            JSON.parseObject(noticeRuleSettingDO.getReceiveDateJson(), HrNoticeDateSettingVO.class);
                    Date runDate = parseRunDate(hrNoticeDateSettingVO);
                    if (ObjectUtils.isEmpty(runDate)) {
                        continue;
                    }
                    // 待增减员未确认人员
                    List<EmpSocPlanDO> planWithCompanyIdList = empSocPlanListGroupCompany.get(companyId);
                    if (CollectionUtils.isEmpty(planWithCompanyIdList)) {
                        continue;
                    }
                    // 取出所有员工Id用逗号隔开
                    String empIdList = planWithCompanyIdList
                            .parallelStream()
                            .map(EmpSocPlanDO::getEmpId)
                            .distinct()
                            .collect(Collectors.joining(","));
                    TaskAddDTO taskAddDTO = new TaskAddDTO();
                    taskAddDTO.setSubjectId(empIdList);
                    taskAddDTO.setSubjectType(NoticeConstants.INCREMENT);
                    taskAddDTO.setDescription(ReceiveDateTypeEnum.FIXED.getDesc());
                    taskAddDTO.setRunType(companyId);
                    taskAddDTO.setRunDate(runDate);
                    taskAddDTO.setRunBeanName("SentNoticeTask");
                    taskAddDTO.setStatus(false);
                    taskKit.addTask(taskAddDTO, tokenUser);
                }
            }
            XxlJobLogger.log("==========检测员工增减员确认发送通知结束");
        } catch (Exception e) {
            XxlJobLogger.log("==========定时任务失败: 检测员工增减员确认发送通知,失败原因 : {}", e.getMessage());
            return ReturnT.FAIL;
        }
        XxlJobLogger.log("==========定时任务结束: 检测员工增减员确认发送通知");
        return ReturnT.SUCCESS;
    }

    /**
     * 解析时间
     */
    public HrNoticeDateSettingVO parseDate(NoticeRuleSettingDO noticeRuleSettingDO) {
        HrNoticeDateSettingVO hrNoticeDateSettingVO = JSON.parseObject(noticeRuleSettingDO.getReceiveDateJson(), HrNoticeDateSettingVO.class);
        // 提前提醒: 单位
        Integer unit = hrNoticeDateSettingVO.getUnit();
        //提前提醒: 数量
        int number = null == hrNoticeDateSettingVO.getNumber() ? 0 : hrNoticeDateSettingVO.getNumber();
        // 将时间提前量转为秒
        int second1 = 0;
        if (hrNoticeDateSettingVO.getAppointTime() != null) {
            String[] split = hrNoticeDateSettingVO.getAppointTime().split(":");
            String m = split[0];
            String s = split[1];
            String s1 = split[2];
            second1 = Integer.parseInt(m) * 60 * 60 + Integer.parseInt(s) * 60 + Integer.parseInt(s1);
        }
        int second = 0;
        if (UNIT_MINUTE.equals(unit)) {
            second = number * 60;
        } else if (UNIT_HOUR.equals(unit)) {
            second = number * 60 * 60;
        } else if (UNIT_DAY.equals(unit)) {
            second = number * 24 * 60 * 60;
        }
        second -= second1;
        log.info("提前时间: {}s", second);
        hrNoticeDateSettingVO.setSecond(second);
        return hrNoticeDateSettingVO;
    }

    /**
     * 获取固定时间
     */
    private Date getFixedDate(Integer day, String time) {

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(DateKit8.getFirstDayOfCurrentMonth());

        // 判断指定天是否比当月最大天数大，取小的
        if (day > calendar.getMaximum(Calendar.DAY_OF_MONTH)) {
            calendar.set(Calendar.DAY_OF_MONTH, calendar.getMaximum(Calendar.DAY_OF_MONTH));
        } else {
            calendar.set(Calendar.DAY_OF_MONTH, day);
        }
        String[] timeSplit = time.split(":");
        calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(timeSplit[0]));
        calendar.set(Calendar.MINUTE, Integer.parseInt(timeSplit[1]));
        calendar.set(Calendar.SECOND, Integer.parseInt(timeSplit[2]));
        return calendar.getTime();
    }

    /**
     * 获取固定时间,和上面那个一样,用哪一个无所谓
     */
    private Date parseRunDate(HrNoticeDateSettingVO hrNoticeDateSettingVO) {
        // 需要每个月发送通知的日期和时分秒
        Integer day = hrNoticeDateSettingVO.getDay();
        String time = hrNoticeDateSettingVO.getTime();
        // 当前年月日
        int currentYear = DateUtils.getCurrentYear();
        String currentMonth = DateUtils.getCurrentMonthStr();
        String currentDay = DateUtils.getCurrentDay();
        // 获取当前月的最后一天
        String currentMonthDayCount = DateUtils.getCurrentMonthDayCount();
        // 当前天数已经超过了发送通知的日期,跳过
        if (Integer.parseInt(currentDay) > day) {
            return null;
        }
        // 如果需要发送的日大于这个月的最大天数,发送日期改到这个月的最后一天
        if (day > Integer.parseInt(currentMonthDayCount)) {
            currentDay = currentMonthDayCount;
        }
        return DateKit8.
                parseDateTime(currentYear + "-" + currentMonth + "-" + currentDay + " " + time);
    }

    /**
     * 获取提醒时间
     */
    private Date getNoticeDate(EmpInfoDO empInfoDO, String noticeTypeCode) {
        String empId = empInfoDO.getId();
        Date date = null;

        // 转正
        if (NoticeConstants.TURN_OFFICIAL.equals(noticeTypeCode)) {
            date = empInfoDO.getTurnStraightDate();
        }
        // 离职
        else if (NoticeConstants.RESIGN.equals(noticeTypeCode)) {
            EmpChangesDO empChangesDO = empChangesService.selectLastResign(empId);
            if (empChangesDO != null) {
                date = empChangesDO.getPreQuitDate();
            }
        }
        // 调岗
        else if (NoticeConstants.TRANSFER.equals(noticeTypeCode)) {
            EmpChangesDO empChangesDO = empChangesService.selectLastTransfer(empId);
            if (empChangesDO != null) {
                date = empChangesDO.getAdjustmentDate();
            }
        }
        // 待入职
        else if (NoticeConstants.INDUCTION.equals(noticeTypeCode)) {
            date = empInfoDO.getJoinDate();
        }

        // 退休
        else if (NoticeConstants.RETIRE.equals(noticeTypeCode)) {
            if (empInfoDO.getRetirementDate() != null) {
                date = empInfoDO.getRetirementDate();
            } else if (empInfoDO.getRetirementAge() != null && !StringUtils.isEmpty(empInfoDO.getBirthday())) {
                Date date1 = DateUtil.parse(empInfoDO.getBirthday());
                date = DateUtil.offset(date1, DateField.YEAR, empInfoDO.getRetirementAge());
                if (date.getTime() - System.currentTimeMillis() < 0) {
                    date = null;
                }
            }
        }

        return date;
    }

}
